package com.agileai.pm.filter;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.jasig.cas.client.authentication.AttributePrincipal;

import com.agileai.hotweb.common.BeanFactory;
import com.agileai.hotweb.common.ClassLoaderFactory;
import com.agileai.hotweb.common.HttpRequestHelper;
import com.agileai.hotweb.common.ModuleManager;
import com.agileai.hotweb.controller.core.BaseHandler;
import com.agileai.hotweb.domain.core.Profile;
import com.agileai.hotweb.domain.core.User;
import com.agileai.hotweb.filter.HotwebUserCacher;
import com.agileai.pm.cxmodule.ProjectInfoManage;
import com.agileai.pm.domain.Consts;
import com.agileai.pm.domain.Project;
import com.agileai.util.StringUtil;

public class HotwebUserCasFilter implements Filter{
	
	@Override
	public void destroy() {
		
	}
	
	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
	    HttpServletRequest httpRequest = (HttpServletRequest) request;
	    AttributePrincipal attributePrincipal =  (AttributePrincipal)httpRequest.getUserPrincipal();
	    if (attributePrincipal != null) {
	        String loginName = attributePrincipal.getName();
	        Profile profile = getProfile(httpRequest);
	        if (profile == null) {
	        	String fromIpAddress = HttpRequestHelper.getRemoteHost(httpRequest);
				String appName = httpRequest.getContextPath().substring(1);
				HotwebUserCacher userCacher = HotwebUserCacher.getInstance(appName);
				User user = userCacher.getUser(loginName);
				
				profile = new Profile(loginName,fromIpAddress,user);
				HttpSession session = httpRequest.getSession(true);
				session.setAttribute(Profile.PROFILE_KEY, profile);
				
				if (user.hasRole(Consts.ProjectMasterRole) || user.isAdmin()){
					String userPk = user.getUserId();
					ProjectInfoManage projectInfoManage = (ProjectInfoManage)this.lookupService("projectInfoManageService");
					List<Project> projectList = projectInfoManage.queryProjectList(userPk);
					if (projectList != null && projectList.size() > 0){
						Project project = projectList.get(0);
						this.getSessionAttributes(httpRequest).put(Consts.ProjectSessionKey, project);
					}else{
						Project project = Project.createEmptyProject();
						this.getSessionAttributes(httpRequest).put(Consts.ProjectSessionKey, project);
					}
				}else{
					String userPk = user.getUserId();
					ProjectInfoManage projectInfoManage = (ProjectInfoManage)this.lookupService("projectInfoManageService");
					List<Project> projectList = projectInfoManage.queryProjectList(userPk);
					if (projectList != null && projectList.size() > 0){
						Project project = projectList.get(0);
						this.getSessionAttributes(httpRequest).put(Consts.ProjectSessionKey, project);
					}
				}				
	        }
	    }
	    chain.doFilter(request, response);		
	}
	
	protected Profile getProfile(HttpServletRequest request){
		Profile profile = null;
		HttpSession session = request.getSession(false);
		if (session != null){
			profile = (Profile)session.getAttribute(Profile.PROFILE_KEY);	
		}
		return profile;
	}
	
	@Override
	public void init(FilterConfig arg0) throws ServletException {
		
	}
	
	@SuppressWarnings("unchecked")
	private HashMap<String,Object> getSessionAttributes(HttpServletRequest request){
		HttpSession session = request.getSession();
		Object temp = session.getAttribute(BaseHandler.HTTP_SESSION_MODEL_KEY);
		if (temp == null){
			HashMap<String,Object> sessionAttributes = new HashMap<String,Object>();
			session.setAttribute(BaseHandler.HTTP_SESSION_MODEL_KEY,sessionAttributes);
			temp = sessionAttributes;
		}
		return (HashMap<String,Object>)temp;
	}	
	
	private Object lookupService(String serviceId){
		Object service = null;
		ClassLoader appClassLoader = Thread.currentThread().getContextClassLoader();
		ModuleManager moduleManager = ModuleManager.getOnly(appClassLoader);
		String moduleName = moduleManager.getServiceModule(serviceId);
		if (StringUtil.isNotNullNotEmpty(moduleName)){
			ClassLoaderFactory classLoaderFactory = ClassLoaderFactory.instance(appClassLoader);
			ClassLoader moduleClassLoader = classLoaderFactory.createModuleClassLoader(moduleName);
			service = BeanFactory.instance(moduleClassLoader).getBean(serviceId);
		}else{
			service = BeanFactory.instance().getBean(serviceId);
		}
		return service;
	}
}
